﻿using System;
using System.Windows.Forms;
using Microsoft.SharePoint;
using FTTXImportUtility.Utility;
using System.Collections;
using System.Drawing;



namespace FTTXImportUtility
{
  public partial class FormMap : Form
  {
    private SPList _sourceList;
    private SPList _targetList;
    private Hashtable _roadMap;
    private object _last = new object();

    #region Constructors
    public FormMap()
    {
      InitializeComponent();
      this.RoadMap = new Hashtable();
      this.listBoxRoadMap.ValueMember = "Object";
      this.listBoxRoadMap.DisplayMember = "Text";
    }

    public FormMap(SPList sourceList, SPList targetList)
      : this()
    {
      this.SourceList = sourceList;
      this.TargetList = targetList;
    }
    #endregion

    #region Events

    private void buttonAddMap_Click(object sender, EventArgs e)
    {

      if (listBoxSource.SelectedItem == null || listBoxTarget.SelectedItem == null)
      {
        this.ShowMessageInformation("Select map first", "Attention");
        return;
      }

      if (this.listBoxRoadMap.Items.Count >= _targetList.Fields.Count)
      {
        this.ShowMessageInformation("Cannot add more than in target list columns", "Attention");
      }

      AddMap();
    }

    private void buttonRemove_Click(object sender, EventArgs e)
    {
      if (this.listBoxRoadMap.SelectedItem == null)
      {
        this.ShowMessageInformation("Select first item which to delete");
        return;
      }
      this.RoadMap.Remove((this.listBoxRoadMap.SelectedItem as ItemTag).TargetField.Id);
      this.listBoxRoadMap.Items.Remove(this.listBoxRoadMap.SelectedItem);
      this.SetMappingCount(listBoxRoadMap.Items.Count);
    }

    private void FormMap_Shown(object sender, EventArgs e)
    {
      this.Cursor = Cursors.WaitCursor;
      this.Refresh();
      FillLists();
      this.Cursor = Cursors.Default;
    }

    private void buttonRemoveAll_Click(object sender, EventArgs e)
    {
      this.listBoxRoadMap.Items.Clear();
      this.RoadMap.Clear();
      this.SetMappingCount(0);
    }

    private void buttonDefault_Click(object sender, EventArgs e)
    {
      RoadMap = AlgorithmDefaultUtility.GetDefaultRoadMap(_targetList, _sourceList);

      listBoxRoadMap.Items.Clear();

      foreach (var key in RoadMap.Keys)
        listBoxRoadMap.Items.Add(RoadMap[key]);
    }

    private void buttonNewColumn_Click(object sender, EventArgs e)
    {
      if (this.listBoxSource.SelectedItem == null)
      {
        this.ShowMessageInformation("Select first source column!");
        return;
      }

      var sourceField = this.listBoxSource.SelectedItem as SPField;

      if (this.TargetList.Fields.ContainsField(sourceField.InternalName))
      {
        this.ShowMessageInformation("There is column with specific name " + sourceField.InternalName);
        return;
      }

      try
      {

        SPField field = TargetList.Fields.CreateNewField(sourceField.TypeAsString, sourceField.Title);

        //field.ShowInDisplayForm = sourceField.ShowInDisplayForm;

        string internalName = TargetList.Fields.Add(field);

        //TargetList.Update();

        field = TargetList.Fields.GetFieldByInternalName(internalName);

        field.ShowInViewForms = true;

        //field.ShowInViewForms = true;

        field.Update();

        /////////////////////////////////////////
        // Put field in default view  
        ////////////////////////////////////////
        SPView view = TargetList.DefaultView;

        if (view != null)
        {
          SPViewFieldCollection fields = view.ViewFields;
          if (fields != null)
          {
            fields.Add(field);
            view.Update();
          }
        }

        this.listBoxTarget.Items.Add(field);

        this.listBoxTarget.SelectedItem = field;

        this.listBoxTarget.TopIndex = this.listBoxTarget.SelectedIndex;

        AddMap();

      }
      catch (Exception ex)
      {
        this.ShowMessageError(ex.Message);
      }

    }

    /// <summary>
    /// http://vbcity.com/forums/t/61061.aspx
    /// <code>
    ///     Private Sub ListBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseMove
    ///         Dim MousePositionInClientCoords As Point = New Point(e.X, e.Y) 
    ///         Dim indexUnderTheMouse As Integer = Me.ListBox1.IndexFromPoint(MousePositionInClientCoords)
    ///         If indexUnderTheMouse > -1 Then
    ///             Dim s As String = Me.ListBox1.Items(indexUnderTheMouse).ToString
    ///             Dim g As Graphics = Me.ListBox1.CreateGraphics
    ///             If g.MeasureString(s, Me.ListBox1.Font).Width > Me.ListBox1.ClientRectangle.Width Then
    ///                 Me.ToolTip1.SetToolTip(Me.ListBox1, s)
    ///             Else
    ///                 Me.ToolTip1.SetToolTip(Me.ListBox1, "")
    ///             End If
    ///             g.Dispose()
    ///         End If
    ///     End Sub
    /// </code>
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void listBox_MouseMove(object sender, MouseEventArgs e)
    {
      ListBox listBox = sender as ListBox;
      var mousePositionInClientCoords = new Point(e.X, e.Y);
      var indexUnderTheMouse = listBox.IndexFromPoint(mousePositionInClientCoords);
      if (indexUnderTheMouse > -1)
      {
        SPField field = listBox.Items[indexUnderTheMouse] as SPField;
        var tip = field.InternalName;
        if (_last != null && !_last.Equals(field))
        {
          this.toolTip1.SetToolTip(listBox, tip);
          _last = field;
        }
      }

    }

    #endregion

    #region Utils

    private void AddMap()
    {
      var sourceItem = listBoxSource.SelectedItem as SPField;
      var targetItem = listBoxTarget.SelectedItem as SPField;

      ItemTag itemTag = null;

      if (sourceItem is SPFieldLookup)
      { 
        string strFormat = "Source field {0}({1}) is SPFieldLookup. Do You want extract only text data from it.";

        DialogResult dialogResult = FormUtility.ShowMessageRequest(this, String.Format(strFormat, sourceItem.Title, sourceItem.InternalName));
        if (dialogResult == System.Windows.Forms.DialogResult.Yes)
          itemTag = AlgorithmDefaultUtility.ConstrainItemTag(sourceItem, targetItem, true);
        else
          itemTag = AlgorithmDefaultUtility.ConstrainItemTag(sourceItem, targetItem, false);
      }
      else
        itemTag = AlgorithmDefaultUtility.ConstrainItemTag(sourceItem, targetItem, false);

      this.listBoxRoadMap.Items.Add(itemTag);
      this.RoadMap[targetItem.Id] = itemTag;
      this.SetMappingCount(listBoxRoadMap.Items.Count);
    }

    private void FillLists()
    {
      this.listBoxSource.SetDataSource(SourceList.Fields, "Title", "ID", false);
      this.listBoxSource.Update();
      this.listBoxTarget.SetDataSource(TargetList.Fields, "Title", "ID", false);
      this.listBoxTarget.Update();
    }

    public void SetSources(SPList sourceList, SPList targetList)
    {
      this.SourceList = sourceList;
      this.TargetList = targetList;
      this.listBoxRoadMap.Items.Clear();
      this.FillLists();
    }


    #endregion

    #region Properties

    public Hashtable RoadMap
    {
      get { return _roadMap; }
      private set
      {
        _roadMap = value;
        SetMappingCount(_roadMap.Count);
      }
    }

    private void SetMappingCount(int count)
    {
      this.label3.Text = string.Format("Result: {0} mappings", count);
    }

    public SPList TargetList
    {
      get { return _targetList; }
      set
      {
        _targetList = value;
        labelTargetTitle.Text = string.Format("Target:{0}", value.Title);
      }
    }

    public SPList SourceList
    {
      get { return _sourceList; }
      set
      {
        _sourceList = value;
        labelSourceTitle.Text = string.Format("Source:{0}", value.Title);
      }
    }
    #endregion

  }
}
